home *** CD-ROM | disk | FTP | other *** search
/ Java Developer's Companion / Java Developer's Companion.iso / documentation / tutorial / example / ButtonFilter.java < prev    next >
Encoding:
Java Source  |  1997-07-13  |  8.1 KB  |  243 lines

  1. /*
  2.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  3.  *
  4.  * Permission to use, copy, modify, and distribute this software
  5.  * and its documentation for NON-COMMERCIAL purposes and without
  6.  * fee is hereby granted provided that this copyright notice
  7.  * appears in all copies. Please refer to the file "copyright.html"
  8.  * for further important copyright and licensing information.
  9.  *
  10.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  11.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  12.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  13.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  14.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  15.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  16.  */
  17. /*
  18.  * @(#)ButtonFilter.java    1.2 95/10/13  
  19.  *
  20.  * Copyright (c) 1994-1995 Sun Microsystems, Inc. All Rights Reserved.
  21.  *
  22.  * Permission to use, copy, modify, and distribute this software
  23.  * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
  24.  * without fee is hereby granted. 
  25.  * Please refer to the file http://java.sun.com/copy_trademarks.html
  26.  * for further important copyright and trademark information and to
  27.  * http://java.sun.com/licensing.html for further important licensing
  28.  * information for the Java (tm) Technology.
  29.  * 
  30.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  31.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  32.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  33.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  34.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  35.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  36.  * 
  37.  * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
  38.  * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
  39.  * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
  40.  * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
  41.  * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
  42.  * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
  43.  * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
  44.  * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
  45.  * HIGH RISK ACTIVITIES.
  46.  */
  47.  
  48. import java.applet.Applet;
  49. import java.awt.Image;
  50. import java.awt.Graphics;
  51. import java.awt.Rectangle;
  52. import java.util.StringTokenizer;
  53. import java.util.Vector;
  54. import java.util.Hashtable;
  55. import java.net.URL;
  56. import java.awt.image.*;
  57. import java.net.MalformedURLException;
  58.  
  59. /**
  60.  * An extensible ImageMap applet class.
  61.  * The active areas on the image are controlled by ImageArea classes
  62.  * that can be dynamically loaded over the net.
  63.  *
  64.  * @author     Jim Graham
  65.  * @version     1.2, 13 Oct 1995
  66.  */
  67. class ButtonFilter extends RGBImageFilter {
  68.     boolean pressed;
  69.     int defpercent;
  70.     int border;
  71.     int width;
  72.     int height;
  73.  
  74.     ColorModel models[] = new ColorModel[7];
  75.     ColorModel origbuttonmodel;
  76.  
  77.     public ButtonFilter(boolean press, int p, int b, int w, int h) {
  78.     pressed = press;
  79.     defpercent = p;
  80.     border = b;
  81.     width = w;
  82.     height = h;
  83.     }
  84.  
  85.     public void setHints(int hints) {
  86.     super.setHints(hints & (~ImageConsumer.COMPLETESCANLINES));
  87.     }
  88.  
  89.     public void setColorModel(ColorModel model) {
  90.     if (model instanceof IndexColorModel && true) {
  91.         IndexColorModel icm = (IndexColorModel) model;
  92.         models[0] = filterIndexColorModel(icm, false, false, 0);
  93.         models[1] = filterIndexColorModel(icm, true, !pressed, defpercent);
  94.         models[2] = null;
  95.         if (pressed) {
  96.         models[3] = filterIndexColorModel(icm, true, false,
  97.                           defpercent/2);
  98.         } else {
  99.         models[3] = models[0];
  100.         }
  101.         models[4] = null;
  102.         models[5] = filterIndexColorModel(icm, true, pressed, defpercent);
  103.         models[6] = models[0];
  104.         origbuttonmodel = model;
  105.         consumer.setColorModel(models[3]);
  106.     } else {
  107.         super.setColorModel(model);
  108.     }
  109.     }
  110.  
  111.     public IndexColorModel filterIndexColorModel(IndexColorModel icm,
  112.                          boolean opaque,
  113.                          boolean brighter,
  114.                          int percent) {
  115.     byte r[] = new byte[256];
  116.     byte g[] = new byte[256];
  117.     byte b[] = new byte[256];
  118.     byte a[] = new byte[256];
  119.     int mapsize = icm.getMapSize();
  120.     icm.getReds(r);
  121.     icm.getGreens(g);
  122.     icm.getBlues(b);
  123.     if (opaque) {
  124.         icm.getAlphas(a);
  125.         for (int i = 0; i < mapsize; i++) {
  126.         int rgb = filterRGB(icm.getRGB(i), brighter, percent);
  127.         a[i] = (byte) (rgb >> 24);
  128.         r[i] = (byte) (rgb >> 16);
  129.         g[i] = (byte) (rgb >> 8);
  130.         b[i] = (byte) (rgb >> 0);
  131.         }
  132.     }
  133.     return new IndexColorModel(icm.getPixelSize(), mapsize, r, g, b, a);
  134.     }
  135.  
  136.     /**
  137.      * Define the ranges of varying highlight for the button.
  138.      * ranges is an array of 8 values which split up a scanline into
  139.      * 7 different regions of highlighting effect:
  140.      *
  141.      * ranges[0-1] = area outside of left edge of button
  142.      * ranges[1-2] = area inside UpperLeft highlight region left of center
  143.      * ranges[2-3] = area requiring custom highlighting left of center
  144.      * ranges[3-4] = area inside center of button
  145.      * ranges[4-5] = area requiring custom highlighting right of center
  146.      * ranges[5-6] = area inside LowerRight highlight region right of center
  147.      * ranges[6-7] = area outside of right edge of button
  148.      *
  149.      * Note that ranges[0-1] and ranges[6-7] are empty where the edges of
  150.      * the button touch the left and right edges of the image (everywhere
  151.      * on a square button) and ranges[2-3] and ranges[4-5] are only nonempty
  152.      * in those regions where the UpperLeft highlighting has leaked over
  153.      * the "top" of the button onto parts of its right edge or where the
  154.      * LowerRight highlighting has leaked under the "bottom" of the button
  155.      * onto parts of its left edge (can't happen on square buttons, happens
  156.      * occasionally on round buttons).
  157.      */
  158.     public void buttonRanges(int y, int ranges[]) {
  159.     ranges[0] = ranges[1] = 0;
  160.     if (y < border) {
  161.         ranges[2] = ranges[3] = ranges[4] = ranges[5] = width - y;
  162.     } else if (y > height - border) {
  163.         ranges[2] = ranges[3] = ranges[4] = ranges[5] = height - y;
  164.     } else {
  165.         ranges[2] = ranges[3] = border;
  166.         ranges[4] = ranges[5] = width - border;
  167.     }
  168.     ranges[6] = ranges[7] = width;
  169.     }
  170.  
  171.     public void setPixels(int x, int y, int w, int h,
  172.               ColorModel model, byte pixels[], int off,
  173.               int scansize) {
  174.     if (model == origbuttonmodel) {
  175.         int ranges[] = new int[8];
  176.         int x2 = x + w;
  177.         for (int cy = y; cy < y + h; cy++) {
  178.         buttonRanges(cy, ranges);
  179.         for (int i = 0; i < 7; i++) {
  180.             if (x2 > ranges[i] && x < ranges[i+1]) {
  181.             int cx1 = Math.max(x, ranges[i]);
  182.             int cx2 = Math.min(x2, ranges[i+1]);
  183.             if (models[i] == null) {
  184.                 super.setPixels(cx1, cy, cx2 - cx1, 1,
  185.                         model, pixels,
  186.                         off + (cx1 - x), scansize);
  187.             } else {
  188.                 if (cx1 < cx2) {
  189.                 consumer.setPixels(cx1, cy, cx2 - cx1, 1,
  190.                            models[i], pixels,
  191.                            off + (cx1 - x), scansize);
  192.                 }
  193.             }
  194.             }
  195.         }
  196.         off += scansize;
  197.         }
  198.     } else {
  199.         super.setPixels(x, y, w, h, model, pixels, off, scansize);
  200.     }
  201.     }
  202.  
  203.     public int filterRGB(int x, int y, int rgb) {
  204.     boolean brighter;
  205.     int percent;
  206.     if ((x < border && y < height - x) || (y < border && x < width - y)) {
  207.         brighter = !pressed;
  208.         percent = defpercent;
  209.     } else if (x >= width - border || y >= height - border) {
  210.         brighter = pressed;
  211.         percent = defpercent;
  212.     } else if (pressed) {
  213.         brighter = false;
  214.         percent = defpercent / 2;
  215.     } else {
  216.         return rgb & 0x00ffffff;
  217.     }
  218.     return filterRGB(rgb, brighter, percent);
  219.     }
  220.  
  221.     public int filterRGB(int rgb, boolean brighter, int percent) {
  222.     int r = (rgb >> 16) & 0xff;
  223.     int g = (rgb >> 8) & 0xff;
  224.     int b = (rgb >> 0) & 0xff;
  225.     if (brighter) {
  226.         r = (255 - ((255 - r) * (100 - percent) / 100));
  227.         g = (255 - ((255 - g) * (100 - percent) / 100));
  228.         b = (255 - ((255 - b) * (100 - percent) / 100));
  229.     } else {
  230.         r = (r * (100 - percent) / 100);
  231.         g = (g * (100 - percent) / 100);
  232.         b = (b * (100 - percent) / 100);
  233.     }
  234.     if (r < 0) r = 0;
  235.     if (g < 0) g = 0;
  236.     if (b < 0) b = 0;
  237.     if (r > 255) r = 255;
  238.     if (g > 255) g = 255;
  239.     if (b > 255) b = 255;
  240.     return (rgb & 0xff000000) | (r << 16) | (g << 8) | (b << 0);
  241.     }
  242. }
  243.